#ifndef DEVICEDRIVER_H
#define DEVICEDRIVER_H

#include "Device.h"

static SEGTYPE lastAllocatedBlock = 0;	//the last block that was given to a process, used in getting next free



/***
 * Holds an FSIB, without the use array
 */
typedef struct FSIB{
	char fs_name[100];					//MUST BE NULL-TERMINATED, so up to 99 chars + '\0'
	unsigned char block_size : 2;		
	unsigned int max_block : 18;
	unsigned int root_block : 18;
}FSIB;

/***
 * Holds an FCB
 */
typedef struct FCB{
	char filename[100];				//MUST BE NULL-TERMINATED, so up to 99 chars + '\0'
	unsigned int filesize : 18;
	unsigned char isDirectory : 1;
}FCB;


/***
 * Gets the overflow block from a given FCB
 */
SEGTYPE get_overflow_block(SEGTYPE blockNum);


/***
 * Reads the index'th (?) address in the FCB address list
 * blockNumber is the block of the FCB
 * Does't actually do anything yet
 */
int read_address(SEGTYPE blockNumber, int index);

/***
 * Adds an address to a FCB address list
 * blockNumber is the block of the FCB
 * returns 0 on fail or 1 on success
 */
int add_address(SEGTYPE blockNumber, SEGTYPE addressToAdd);


/***
 * Sets an address within an FCB address list.
 * @author Daniel Fairweather, but mostly copied from Jan!
 * @param blockNumber The block containing an FCB.
 */
void set_address(SEGTYPE blockNumber, int index, SEGTYPE addressToAdd);


/***
 * Finds the next free block
 * returns 0 if none found
 */
SEGTYPE get_free_block();



/***
 * Writes the FSIB to the BS.
 * Doesn't include the use table/array thingy.
 * The FSIB is written to the first 800 + 2 + 18 + 18 bits.
 */
void write_FSIB(FSIB* fsib);

/***
 * Reads an FSIB from the BS.
 * Stores results in buffer passed to it.
 */
void read_FSIB(FSIB* buffer);



/***
 * Writes an FCB to a block. 
 * Works just like FSIB write except with an extra parameter
 */
void write_FCB(FCB* fcb, SEGTYPE blockNumber);

/***
 * Reads an FCB from a block.
 * Works just like FSIB read except with an extra parameter
 */
void read_FCB(FCB* buffer, SEGTYPE blockNumber);



/***
 * Reads a number of bits (up to SEGMENT_SIZE) from backingstore and assigns them
 * to a variable. Cast what it returns to whatever it's supposed to be.
 * It'll read bits from (startBit) to (startBit + bitsToRead - 1) inclusive
 */
SEGTYPE read_var_from_bs(SEGTYPE startBit, int bitsToRead);

/***
 * Writes a variable to the backingstore. Cast whatever you need to write 
 * to a SEGTYPE and specify how big it is (works up to SEGMENT_SIZE bits) with bitsToWrite.
 * It'll write to bits from (startBit) to (startBit + bitsToWrite - 1) inclusive
 */
void write_var_to_bs(SEGTYPE toWrite, SEGTYPE startBit, int bitsToWrite);

#endif